﻿using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace K9Nano.Serialize
{
    public class DefaultBinarySerializer : ISerializer
    {
        public byte[] Serialize(object obj)
        {
            if (obj == null) return new byte[0];
            if (obj is byte[] bytes) return bytes;

            var formatter = new BinaryFormatter();
            using var ms = new MemoryStream();
            formatter.Serialize(ms, obj);
            return ms.GetBuffer();
        }

        public string SerializeToString(object obj)
        {
            return Convert.ToBase64String(Serialize(obj));
        }

        public T Deserialize<T>(byte[] bytes)
        {
            if (bytes == null) throw new ArgumentNullException(nameof(bytes));
            if (typeof(T) == typeof(byte[]))
            {
                return (T) (object) bytes;
            }
            
            using var ms = new MemoryStream(bytes);
            var formatter = new BinaryFormatter();
            var result = formatter.Deserialize(ms);
            return (T)result;
        }

        public object Deserialize(string data, Type type)
        {
           var bytes = Convert.FromBase64String(data);

           if (type == typeof(byte[])) return bytes;

           using var ms = new MemoryStream(bytes);
           var formatter = new BinaryFormatter();
           var result = formatter.Deserialize(ms);

           return result;
        }
    }
}